package com.csw.android.androidtest.module.storage;

import com.csw.android.androidtest.app.MyApplication;
import com.csw.android.androidtest.entities.Student;
import com.csw.android.androidtest.ui.LogViewFragment;
import com.csw.android.dev_utils.utils.FileUtils;
import com.csw.android.dev_utils.utils.GSONUtils;
import com.csw.android.dev_utils.utils.ToastUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Action;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;

/**
 * 文件存储
 * <p>
 * 早期的android版本允许存储到sd卡公开目录，导致很多应用在里面随意创建文件夹存储（如qq），导致用户sd卡文件夹
 * 混乱不堪，存放到公开目录的数据不会随app卸载而删除，体现的优点是用户卸载后过段时间再安装可以继承之前的配置，
 * 缺点是，用户sd卡混乱，占用严重。
 * <p>
 * android9.0以后增加分区存储，即使获取权限也不允许读写公开目录，提倡通过MediaStore的api来读写公开目录文件。
 * <p>
 * 一般还是建议存储在应用目录(./android/data/packageName/file|cache或者私有目录)下，
 */
public class FileStorageTest extends LogViewFragment {

    @Override
    public void initData() {
        super.initData();
        Student student = new Student("蔡树伟", "男", 28);

        saveStudent(student);
    }

    private void saveStudent(Student student) {
        Observable.just(student)
                .observeOn(Schedulers.io())
                .doOnNext(new Consumer<Student>() {
                    @Override
                    public void accept(Student student) throws Exception {
                        //进行序列化便于存储
                        String dataStr = GSONUtils.INSTANCE.toJSONString(student);

                        //./android/data/packageName/file/config/student.instance
                        File appRoot = MyApplication.instance.getExternalFilesDir(null);
                        if (appRoot != null) {
                            String filePath = appRoot.getAbsolutePath() + File.separator + "config";
                            String fileName = filePath + File.separator + "student.instance";
                            FileUtils.INSTANCE.generateDirectory(filePath);
                            File file = new File(fileName);
                            FileUtils.INSTANCE.deleteFile(file);
                            FileUtils.INSTANCE.generateFile(file);

                            FileOutputStream fos = new FileOutputStream(file);
                            fos.write(dataStr.getBytes());
                            fos.flush();
                        }
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .doOnError(new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        throwable.printStackTrace();
                        ToastUtils.INSTANCE.showShort("存储失败", ToastUtils.INSTANCE.getDEFAULT_TOAST());
                    }
                })
                .doOnComplete(new Action() {
                    @Override
                    public void run() throws Exception {
                        readStudent();
                    }
                }).subscribe();

    }

    private void readStudent() {
        Observable.create(new ObservableOnSubscribe<Student>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<Student> emitter) throws Exception {
                //./android/data/packageName/file/config/student.instance
                File appRoot = MyApplication.instance.getExternalFilesDir(null);
                if (appRoot != null) {
                    String filePath = appRoot.getAbsolutePath() + File.separator + "config";
                    String fileName = filePath + File.separator + "student.instance";

                    StringBuilder sb = new StringBuilder();
                    BufferedReader bufferedReader = new BufferedReader(new FileReader(fileName));
                    String line;
                    while ((line = bufferedReader.readLine()) != null) {
                        sb.append(line);
                    }
                    //读取出json字符串，反序列化
                    String dataStr = sb.toString();
                    Student student = GSONUtils.INSTANCE.parseObject(dataStr,Student.class);
                    if(!emitter.isDisposed()){
                        emitter.onNext(student);
                    }
                    if(!emitter.isDisposed()){
                        emitter.onComplete();
                    }
                }
            }
        })
                .observeOn(AndroidSchedulers.mainThread())
                .doOnNext(new Consumer<Student>() {
                    @Override
                    public void accept(Student student) throws Exception {
                        logView.addLog(student.getName());
                        logView.addLog(student.getSex());
                        logView.addLog(student.getAge());
                    }
                })
                .doOnError(new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        throwable.printStackTrace();
                        ToastUtils.INSTANCE.showShort("读取失败", ToastUtils.INSTANCE.getDEFAULT_TOAST());
                    }
                })
                .subscribe();
    }

}
